﻿-- Author      : Kurapica
-- Create Date : 6/12/2008 1:13:21 AM

-- Region
do
	-- Check Version
	local version = 1
	if not IGAS:RegisterFile("IGAS.GUI.Widget.Region", version) then
		return
	end

    local getmetatable = getmetatable
    local pairs = pairs
    local ipairs = ipairs
    local type = type
    local error = error
    local CreateFrame = CreateFrame
    
	local _WidgetName = "Region"
    local _Base = "UIObject"

	local _GUI = IGAS.GUI
	local _Widget = IGAS.GUI.Widget
    local _BaseFunc = IGAS.GUI.Base.Func
	local _PropertyType = IGAS.GUI.Base.PropertyType
    
    -- FuncProxy
	local _FuncProxy = {
        --- Original Functions
        -- ClearAllPoints() - Clear all attachment points for this object. 
        ["ClearAllPoints"] = function(self)
            self.__UI:ClearAllPoints()
        end,
        
        -- GetBottom() - Get the y location of the bottom edge of this frame
        ["GetBottom"] = function(self)
            return self.__UI:GetBottom()
        end,
        
        -- GetCenter() - Get the coordinates of the center of this frame
        ["GetCenter"] = function(self)
            return self.__UI:GetCenter()
        end,
        
        -- GetHeight() - Get the height of this object. 
        ["GetHeight"] = function(self)
            return self.__UI:GetHeight()
        end,
        
        -- SetHeight(height) - Set the height of the object. 
        ["SetHeight"] = function(self, height)
            self.__UI:SetHeight(height)
        end,
        
        -- GetLeft() - Get the x location of the left edge of this frame
        ["GetLeft"] = function(self)
            return self.__UI:GetLeft()
        end,
        
        -- GetNumPoints() - Get the number of anchor points for this frame
        ["GetNumPoints"] = function(self)
            return self.__UI:GetNumPoints()
        end,
        
        -- GetParent() - Get the parent of this frame (The object, not just the name)
        ["GetParent"] = function(self)
            return self.__Parent or self.__UI:GetParent()
        end,
        
        -- GetPoint(pointNum) - Get details for an anchor point for this frame (point, relativeTo, relativePoint, xofs, yofs)
        ["GetPoint"] = function(self, pointNum)
            point, frame, relativePoint, x, y = self.__UI:GetPoint(pointNum)
            frame = _BaseFunc.GetWrapper(frame)
            return point, frame, relativePoint, x, y
        end,
        
        -- GetRight() - Get the x location of the right edge of this frame
        ["GetRight"] = function(self)
            return self.__UI:GetRight()
        end,
        
        -- GetTop() - Get the y location of the top edge of this frame
        ["GetTop"] = function(self)
            return self.__UI:GetTop()
        end,
        
        -- GetWidth() - Get the width of this object. 
        ["GetWidth"] = function(self)
            return self.__UI:GetWidth()
        end,
        
        -- SetWidth(width) - Set the width of the object. 
        ["SetWidth"] = function(self, width)
            self.__UI:SetWidth(width)
        end,
        
        -- Hide() - Set this object to hidden (it and all of its children will disappear). 
        ["Hide"] = function(self)
            return self.__UI:Hide()
        end,
        
        -- Show() - Set this object to shown (it will appear if its parent is visible). 
        ["Show"] = function(self)
            self.__UI:Show()
        end,
        
        -- IsProtected() - Determine if this object can be manipulated in certain ways by tainted code in combat or not 
        ["IsProtected"] = function(self)
            return self.__UI:IsProtected()
        end,
        
        -- IsShown() - Determine if this object is shown (would be visible if its parent was visible). 
        ["IsShown"] = function(self)
            return self.__UI:IsShown()
        end,
        
        -- IsVisible() - Get whether the object is visible on screen (logically (IsShown() and GetParent():IsVisible())); 
        ["IsVisible"] = function(self)
            return self.__UI:IsVisible()
        end,
        
        -- SetAllPoints(frame or "frameName") - Set all anchors to match edges of specified frame
        ["SetAllPoints"] = function(self, frame)
            local _fra = frame
            
            if type(_fra) == "string" then
                _fra = _G[_fra]
            end
            
            if not _fra  then
                error("no such frame")
            end
            
            _fra = _BaseFunc.GetUI(_fra)
            
            self.__UI:SetAllPoints(_fra)
        end,
        
        -- SetParent(parent or "parentName") - Set the parent for this frame
        ["SetParent"] = function(self, parent)
            local _par = parent
            
            if _par then
                if type(_par) == "string" then
                    _par = _G[_par]
                end
                
                if not _par then
                    error("no such frame")
                end
                
                _par = _BaseFunc.GetWrapper(_par)
				
                -- Add self to new parent's childs
                if _par["IsIGASWidget"] and _par["AddChild"] then
                    _par:AddChild(self)
				else
					error("This object can't add child.")
                end                
            else
                -- Removed self from parent's childs
                if self.__Parent and self.__Parent["IsIGASWidget"] then
                    self.__Parent:RemoveChild(self)
                end
            end
        end,
        
        -- SetPoint("point","relativeFrame" or relativeObject,"relativePoint"[, xOfs, yOfs]) - Set an attachment point of this object - Updated in 1.10. Since 2.2 cooordinates are now relative to the closest anchor point 
        ["SetPoint"] = function(self, point, relativeObject, relativePoint, xOfs, yOfs)
            local _relativeObject = relativeObject
            
            if _relativeObject then
                if type(_relativeObject) == "string" then
                    _relativeObject = _G[_relativeObject]
                end
                
                _relativeObject = _BaseFunc.GetUI(_relativeObject)
                
                self.__UI:SetPoint(point, _relativeObject, relativePoint, xOfs, yOfs)
            end
        end,
        
        -- Dispose, release resource
        ["Dispose"] = function(self)
            self:ClearAllPoints()
            self:Hide()
            
            -- Call super's dispose
            if _Widget[_Base]["FuncProxy"]["Dispose"] then
            	_Widget[_Base]["FuncProxy"]["Dispose"](self)
            end
        end,
        
    }
    
    -- Property
	local _Property = {
		--- Height
		["Height"] = {
			["Set"] = function(self, height)
				self:SetHeight(height)
			end,

			["Get"] = function(self)
				return self:GetHeight()
			end,

			["Type"] = _PropertyType.Number,
		},
		--- Width
		["Width"] = {
			["Set"] = function(self, width)
				self:SetWidth(width)
			end,

			["Get"] = function(self)
				return self:GetWidth()
			end,

			["Type"] = _PropertyType.Number,
		},
		--- Visible
		["Visible"] = {
			["Set"] = function(self, visible)
				if not self.InDesignMode then
					if visible then
						self:Show()
					else
						self:Hide()
					end
				else
					self.__Visible = (visible and true) or false
				end
			end,

			["Get"] = function(self)
				if not self.InDesignMode then
					return (self:IsShown() and true ) or false
				else
					return (self.__Visible and true) or false
				end
			end,

			["Type"] = _PropertyType.Boolean,
		},
		--- Points
		["Points"] = {
			["Set"] = function(self, points)
				self:ClearAllPoints()
				for _, point in ipairs(points) do
					if point.point then
						self:SetPoint(point.point, point.frame, point.relativePoint, point.x, point.y)
					end
				end
			end,

			["Get"] = function(self) 
				local points = {}

				for i = 1, self:GetNumPoints(), 1 do
					local point = {}
					point.point, point.frame, point.relativePoint, point.x, point.y = self:GetPoint(i)
					table.insert(points, point)
				end

				return points
			end,

			["Type"] = _PropertyType.PointArray,
		},
		--- Parent
		["Parent"] = {			
			["Set"] = function(self, parent)
				self:SetParent(parent)
			end,

			["Get"] = function(self)
				return self:GetParent()
			end,

			["Type"] = _PropertyType.Object,
		},
    }
		
    local _WidgetInfo = {
        ["WidgetName"] = _WidgetName,
        ["Base"] = _Base,
        ["FuncProxy"] = _FuncProxy,
        ["Property"] = _Property,
    }
    
    _Widget[_WidgetName] = _GUI.NewWidget(_WidgetInfo)
end